package api

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)


// AccessToken access_token
var AccessToken = ""
// Addr 请先确保use_http is true
// Addr coolq http api config host:port
var Addr = ""


func newPostRequest(urls string, args url.Values) {
	res, err := http.PostForm(fmt.Sprintf(urls, Addr, AccessToken), args)
	if err != nil {
		return
	}
	defer res.Body.Close()
}


func requestGetResp(url, args string)([]byte, error){
	res, err := http.Post(
		fmt.Sprintf(url, Addr, AccessToken),
		"application/x-www-form-urlencoded",
		strings.NewReader(args),
	)
	if err != nil{
		return nil, err
	}
	defer res.Body.Close()
	d, err := ioutil.ReadAll(res.Body)
	if err != nil {
        return nil, err
	}
	return d, nil
}


func testCode(b []byte, name string)(string){
	var m map[string]interface{}
	json.Unmarshal(b, &m)
	data, _ := m["data"].(map[string]interface{})
	str, _ := data[name].(string)
	return str
}


// SendPrivateMsg .发送私聊消息
func SendPrivateMsg(userID int64, message string, autoEscape bool){
	urls := "http://%v/send_private_msg_async?access_token=%v"
	args := url.Values{
		"user_id": {strconv.FormatInt(userID, 10)},
		"message": {message},
		"auto_escape": {strconv.FormatBool(autoEscape)},
	}
	newPostRequest(urls, args)
}


// SendGroupMsg .发送群消息
func SendGroupMsg(groupID int64, message string, autoEscape bool) {
	urls := "http://%v/send_group_msg_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"message": {message},
		"auto_escape": {strconv.FormatBool(autoEscape)},
	}
	newPostRequest(urls, args)
}


// SenDiscussMsg .发送讨论组消息
func SenDiscussMsg(discussID int64, message string, autoEscape bool){
	urls := "http://%v/send_discuss_msg_async?access_token=%v"
	args := url.Values{
		"discuss_id": {strconv.FormatInt(discussID, 10)},
		"message": {message},
		"auto_escape": {strconv.FormatBool(autoEscape)},
	}
	newPostRequest(urls, args)
}


// DeleteMsg .撤回消息
func DeleteMsg(messageID int32){
	urls := "http://%v/delete_msg_async?access_token=%v"
	args := url.Values{
		"message_id": {strconv.FormatInt(int64(messageID), 10)},
	}
	newPostRequest(urls, args)
}


// SendLike .发送好友赞
func SendLike(userID int64, times int){
	urls := "http://%v/send_like_async?access_token=%v"
	args := url.Values{
		"user_id": {strconv.FormatInt(userID, 10)},
		"times": {strconv.Itoa(times)},
	}
	newPostRequest(urls, args)
}



// SetGroupKick .群组踢人
func SetGroupKick(groupID, userID int64, rejectAddRequest bool){
	urls := "http://%v/set_group_kick_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"user_id": {strconv.FormatInt(userID, 10)},
		"reject_add_request": {strconv.FormatBool(rejectAddRequest)},
	}
	newPostRequest(urls, args)
}


// SetGroupBan .群组单人禁言
func SetGroupBan(groupID, userID int64, duration int){
	urls := "http://%v/set_group_ban_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"user_id": {strconv.FormatInt(userID, 10)},
		"duration": {strconv.Itoa(duration)},
	}
	newPostRequest(urls, args)
}


// SetGroupWholeBan .群组全员禁言
func SetGroupWholeBan(groupID int64, enable bool){
	urls := "http://%v/set_group_whole_ban_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"enable": {strconv.FormatBool(enable)},
	}
	newPostRequest(urls, args)
}


// SetGroupAdmin .群组设置管理员
func SetGroupAdmin(groupID, userID int64, enable bool){
	urls := "http://%v/set_group_admin_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"user_id": {strconv.FormatInt(userID, 10)},
		"enable": {strconv.FormatBool(enable)},
	}
	newPostRequest(urls, args)
}


// SetGroupCard .设置群名片（群备注）
func SetGroupCard(groupID, userID int64, card string){
	urls := "http://%v/set_group_card_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"user_id": {strconv.FormatInt(userID, 10)},
		"card": {card},
	}
	newPostRequest(urls, args)
}


// SetGroupLeave .退出群组
func SetGroupLeave(groupID int64, isDismiss bool){
	urls := "http://%v/set_group_leave_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"is_dismiss": {strconv.FormatBool(isDismiss)},
	}
	newPostRequest(urls, args)
}


// SetGroupSpecialTitle .设置群组专属头衔
func SetGroupSpecialTitle(groupID, userID int64, specialTitle string, duration int){
	urls := "http://%v/set_group_special_title_async?access_token=%v"
	args := url.Values{
		"group_id": {strconv.FormatInt(groupID, 10)},
		"user_id": {strconv.FormatInt(userID, 10)},
		"special_title": {specialTitle},
		"duration": {strconv.Itoa(duration)},
	}
	newPostRequest(urls, args)
}


// SetDiscussLeave .退出讨论组
func SetDiscussLeave(discussID int64){
	urls := "http://%v/set_discuss_leave_async?access_token=%v"
	args := url.Values{
		"discuss_id": {strconv.FormatInt(discussID, 10)},
	}
	newPostRequest(urls, args)
}


// SetFriendAddRequest .处理加好友请求
func SetFriendAddRequest(flag string, approve bool, remark string){
	urls := "http://%v/set_friend_add_request_async?access_token=%v"
	args := url.Values{
		"flag": {flag},
		"approve": {strconv.FormatBool(approve)},
		"remark": {remark},
	}
	newPostRequest(urls, args)
}


// SetGroupAddRequest .处理加群请求／邀请
func SetGroupAddRequest(flag, subType, _type string, approve bool, reason string){
	urls, args := "", make(url.Values)
	if _type != ""{
		urls = "http://%v/set_group_add_request_async?access_token=%v"
		args = url.Values{
			"flag": {flag},
			"_type": {_type},
			"approve": {strconv.FormatBool(approve)},
			"reason": {reason},
		}
	}else if subType != ""{
		urls = "http://%v/set_group_add_request_async?access_token=%v"
		args = url.Values{
			"flag": {flag},
			"sub_type": {subType},
			"approve": {strconv.FormatBool(approve)},
			"reason": {reason},
		}
	}
	newPostRequest(urls, args)
}


// GetLoginInfo .获取登录号信息
func GetLoginInfo() (userID int64, nickName string, err error) {
	urls := "http://%v/get_login_info?access_token=%v"
	b, err := requestGetResp(urls, "")
	if err != nil{
		return 0, "", err
	}
	var m map[string]interface{}
	json.Unmarshal(b, &m)
	data, _ := m["data"].(map[string]interface{})
	userI, _ := data["user_id"].(float64)
	userID = int64(userI)
	nickName, _ = data["nickname"].(string)
	return userID, nickName, nil
}


// StrangerInfo .
type StrangerInfo struct{
	Data []struct{
		GroupID int64 `json:"group_id"`
		GroupName string `json:"group_name"`
		MaxMemberCount int `json:"max_member_count"`
		MemberCount int `json:"member_count"`
	} `json:"data"`
}


// GetStrangerInfo .获取陌生人信息
func GetStrangerInfo(userID int64, noCache bool) (*StrangerInfo, error) {
	urls := "http://%v/get_stranger_info?access_token=%v"
	args := fmt.Sprintf(
		"user_id=%v&no_cache=%v",
		userID, noCache,
	)
	b, err := requestGetResp(urls, args)
	if err != nil{
		return nil, err
	}
	m := &StrangerInfo{}
	json.Unmarshal(b, m)
	return m, nil
}


// FriendList .
type FriendList struct{
	Data []struct{
		UserID int64 `json:"user_id"`
		NickName string `json:"nickname"`
		Remark string `json:"remark"`
	} `json:"data"`
} 


// GetFriendList .获取好友列表
func GetFriendList()(*FriendList, error){
	urls := "http://%v/get_friend_list?access_token=%v"
	b, err := requestGetResp(urls, "")
	if err != nil{
		return nil, err
	}
	m := &FriendList{}
	json.Unmarshal(b, m)
	return m, nil
}


// GroupList .
type GroupList struct{
	Data []struct{
		GroupID int64 `json:"group_id"`
		GroupName string `json:"group_name"`
	} `json:"data"`
}


// GetGroupList .获取群列表
func GetGroupList()(*GroupList, error){
	urls := "http://%v/get_group_list?access_token=%v"
	b, err := requestGetResp(urls, "")
	if err != nil{
		return nil, err
	}
	m := &GroupList{}
	json.Unmarshal(b, m)
	return m, nil
}


// GetCookies .获取Cookies
func GetCookies(domain string)(string, error){
	urls := "http://%v/get_cookies?access_token=%v"
	args := fmt.Sprintf(
		"domain=%v",
		domain,
	)
	b, err := requestGetResp(urls, args)
	if err != nil{
		return "", err
	}
	cookies := testCode(b, "cookies")
	return cookies, nil
}


// GetCSRFToken .获取CSRF_Token
func GetCSRFToken()(string, error){
	urls := "http://%v/get_csrf_token?access_token=%v"
	b, err := requestGetResp(urls, "")
	if err != nil{
		return "", err
	}
	token := testCode(b, "token")
	return token, nil
}


// GetRecord .获取语音
func GetRecord(file, outFormat string, fullPath bool)(string, error){
	urls := "http://%v/get_record?access_token=%v"
	args := fmt.Sprintf(
		"file=%v&out_format=%v&full_path=%v",
		file, outFormat, fullPath,
	)
	b, err := requestGetResp(urls, args)
	if err != nil{
		return "", err
	}
	recordPath := testCode(b, "file")
	return recordPath, nil
}


// GetImage .获取图片
func GetImage(file string)(string, error){
	urls := "http://%v/get_image?access_token=%v"
	args := fmt.Sprintf(
		"file=%v",
		file,
	)
	b, err := requestGetResp(urls, args)
	if err != nil{
		return "", err
	}
	imagePath := testCode(b, "file")
	return imagePath, nil
}


// CanSendImage .检查是否可以发送图片
func CanSendImage()(bool, error){
	urls := "http://%v/can_send_image?access_token=%v"
	b, err := requestGetResp(urls, "")
	if err != nil{
		return false, err
	}
	var m map[string]interface{}
	json.Unmarshal(b, &m)
	data, _ := m["data"].(map[string]interface{})
	yes, _ := data["yes"].(bool)
	return yes, nil
}


// CanSendRecord .检查是否可以发送语音
func CanSendRecord()(bool, error){
	urls := "http://%v/can_send_record?access_token=%v"
	b, err := requestGetResp(urls, "")
	if err != nil{
		return false, err
	}
	var m map[string]interface{}
	json.Unmarshal(b, &m)
	data, _ := m["data"].(map[string]interface{})
	yes, _ := data["yes"].(bool)
	return yes, nil
}
